//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.jim.server.helper.redis;

import com.alibaba.fastjson.JSONObject;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jim.core.cache.redis.JedisTemplate;
import org.jim.core.cache.redis.RedisCache;
import org.jim.core.cache.redis.RedisCacheManager;
import org.jim.core.config.ImConfig.Global;
import org.jim.core.listener.ImStoreBindListener;
import org.jim.core.message.AbstractMessageHelper;
import org.jim.core.packets.ChatBody;
import org.jim.core.packets.Group;
import org.jim.core.packets.User;
import org.jim.core.packets.UserMessageData;
import org.jim.core.packets.UserStatusType;
import org.jim.core.utils.JsonKit;
import org.jim.server.util.ChatKit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class RedisMessageHelper extends AbstractMessageHelper {
	private Logger log = LoggerFactory.getLogger(RedisMessageHelper.class);
	private static final String SUFFIX = ":";

	public RedisMessageHelper() {
		this.imConfig = Global.get();
	}

	public ImStoreBindListener getBindListener() {
		return new RedisImStoreBindListener(this.imConfig, this);
	}

	public boolean isOnline(String userId) {
		try {
			String keyPattern = "user:" + userId + ":" + "terminal";
			Set<String> terminalKeys = JedisTemplate.me().keys(keyPattern);
			if (CollectionUtils.isEmpty(terminalKeys)) {
				return false;
			}

			Iterator<String> terminalKeyIterator = terminalKeys.iterator();

			while(terminalKeyIterator.hasNext()) {
				String terminalKey = (String)terminalKeyIterator.next();
				terminalKey = terminalKey.substring(terminalKey.indexOf(userId));
				String isOnline = (String)RedisCacheManager.getCache("user").get(terminalKey, String.class);
				if (UserStatusType.ONLINE.getStatus().equals(isOnline)) {
					return true;
				}
			}
		} catch (Exception var7) {
			this.log.error(var7.toString(), var7);
		}

		return false;
	}

	public User getUserByType(String userId, Integer type) {
		User user = (User)RedisCacheManager.getCache("user").get(userId + ":" + "info", User.class);
		if (Objects.isNull(user)) {
			return null;
		} else {
			boolean isOnline = this.isOnline(userId);
			String status = isOnline ? UserStatusType.ONLINE.getStatus() : UserStatusType.OFFLINE.getStatus();
			if (UserStatusType.ONLINE.getNumber() == type && isOnline) {
				user.setStatus(status);
				return user;
			} else if (UserStatusType.OFFLINE.getNumber() == type && !isOnline) {
				user.setStatus(status);
				return user;
			} else if (type == UserStatusType.ALL.getNumber()) {
				user.setStatus(status);
				return user;
			} else {
				return null;
			}
		}
	}

	private void validateStatusByType(Integer type, List<User> users, User user) {
		String status = user.getStatus();
		if (UserStatusType.ONLINE.getNumber() == type && UserStatusType.ONLINE.getStatus().equals(status)) {
			users.add(user);
		} else if (UserStatusType.OFFLINE.getNumber() == type && UserStatusType.OFFLINE.getStatus().equals(status)) {
			users.add(user);
		} else if (UserStatusType.ALL.getNumber() == type) {
			users.add(user);
		}

	}

	public boolean initUserStatus(User user) {
		if (!Objects.isNull(user) && !Objects.isNull(user.getUserId())) {
			String userId = user.getUserId();
			boolean isOnline = this.isOnline(userId);
			if (isOnline) {
				user.setStatus(UserStatusType.ONLINE.getStatus());
			} else {
				user.setStatus(UserStatusType.OFFLINE.getStatus());
			}

			return true;
		} else {
			return false;
		}
	}

	public Group getGroupUsers(String groupId, Integer type) {
		if (!Objects.isNull(groupId) && !Objects.isNull(type)) {
			Group group = (Group)RedisCacheManager.getCache("group").get(groupId + ":" + "info", Group.class);
			if (Objects.isNull(group)) {
				return null;
			} else {
				List<String> userIds = this.getGroupUsers(groupId);
				if (CollectionUtils.isEmpty(userIds)) {
					return null;
				} else {
					List<User> users = new ArrayList();
					userIds.forEach((userId) -> {
						User user = this.getUserByType(userId, type);
						if (!Objects.isNull(user)) {
							this.validateStatusByType(type, users, user);
						}
					});
					group.setUsers(users);
					return group;
				}
			}
		} else {
			this.log.warn("group:{} or type:{} is null", groupId, type);
			return null;
		}
	}

	public List<Group> getAllGroupUsers(String userId, Integer type) {
		if (Objects.isNull(userId)) {
			return null;
		} else {
			List<String> groupIds = RedisCacheManager.getCache("user").listGetAll(userId + ":" + "group");
			if (CollectionUtils.isEmpty(groupIds)) {
				return null;
			} else {
				List<Group> groups = new ArrayList();
				groupIds.forEach((groupId) -> {
					Group group = this.getGroupUsers(groupId, type);
					if (!Objects.isNull(group)) {
						groups.add(group);
					}
				});
				return groups;
			}
		}
	}

	public List<Group> getAllFriendUsers(String userId, Integer type) {
		if (Objects.isNull(userId)) {
			return null;
		} else {
			List<JSONObject> friendJsonArray = (List)RedisCacheManager.getCache("user").get(userId + ":" + "friends", List.class);
			if (CollectionUtils.isEmpty(friendJsonArray)) {
				return null;
			} else {
				List<Group> friends = new ArrayList();
				friendJsonArray.forEach((groupJson) -> {
					Group group = (Group)JSONObject.toJavaObject(groupJson, Group.class);
					List<User> users = group.getUsers();
					if (!CollectionUtils.isEmpty(users)) {
						List<User> userResults = new ArrayList();
						Iterator var7 = users.iterator();

						while(var7.hasNext()) {
							User user = (User)var7.next();
							this.initUserStatus(user);
							this.validateStatusByType(type, userResults, user);
						}

						group.setUsers(userResults);
						friends.add(group);
					}
				});
				return friends;
			}
		}
	}

	public Group getFriendUsers(String userId, String friendGroupId, Integer type) {
		boolean isTrue = Objects.isNull(userId) || Objects.isNull(friendGroupId) || Objects.isNull(type);
		if (isTrue) {
			this.log.warn("userId:{} or friendGroupId:{} or type:{} is null");
			return null;
		} else {
			List<Group> friends = (List)RedisCacheManager.getCache("user").get(userId + ":" + "friends", List.class);
			if (CollectionUtils.isEmpty(friends)) {
				return null;
			} else {
				Iterator var6 = friends.iterator();

				Group group;
				do {
					if (!var6.hasNext()) {
						return null;
					}

					group = (Group)var6.next();
				} while(!friendGroupId.equals(group.getGroupId()));

				List<User> users = group.getUsers();
				if (CollectionUtils.isEmpty(users)) {
					return group;
				} else {
					List<User> userResults = new ArrayList();
					Iterator var10 = users.iterator();

					while(var10.hasNext()) {
						User user = (User)var10.next();
						this.initUserStatus(user);
						this.validateStatusByType(type, userResults, user);
					}

					group.setUsers(userResults);
					return group;
				}
			}
		}
	}

	public List<String> getGroups(String userId) {
		return RedisCacheManager.getCache("user").listGetAll(userId + ":" + "group");
	}

	public void addGroupUser(String userId, String groupId) {
		List<String> userIds = RedisCacheManager.getCache("group").listGetAll(groupId + ":user");
		if (!userIds.contains(userId)) {
			RedisCacheManager.getCache("group").listPushTail(groupId + ":user", userId);
		}
	}

	public void addUserGroup(String userId, String groupId) {
		List<String> groupIds = RedisCacheManager.getCache("user").listGetAll(userId + ":" + "group");
		if (!groupIds.contains(groupId)) {
			RedisCacheManager.getCache("user").listPushTail(userId + ":" + "group", groupId);
		}
	}

	public void removeGroupUser(String userId, String groupId) {
		RedisCacheManager.getCache("group").listRemove(groupId + ":user", userId);
	}

	public void removeUserGroup(String userId, String groupId) {
		RedisCacheManager.getCache("user").listRemove(userId + ":group", groupId);
	}

	public List<String> getGroupUsers(String groupId) {
		String groupUserKey = groupId + ":" + "user";
		return RedisCacheManager.getCache("group").listGetAll(groupUserKey);
	}

	public void writeMessage(String timelineTable, String timelineId, ChatBody chatBody) {
		double score = (double)chatBody.getCreateTime();
		RedisCacheManager.getCache(timelineTable).sortSetPush(timelineId, score, chatBody);
	}

	public UserMessageData getUserOfflineMessage(String userId) {
		UserMessageData messageData = new UserMessageData(userId);

		try {
			Set<String> userKeys = JedisTemplate.me().keys("push:user:" + userId);
			if (CollectionUtils.isNotEmpty(userKeys)) {
				List<ChatBody> messageList = new ArrayList();
				Iterator<String> userKeyIterator = userKeys.iterator();

				while(userKeyIterator.hasNext()) {
					String userKey = (String)userKeyIterator.next();
					userKey = userKey.substring(userKey.indexOf("user:"));
					List<String> messages = RedisCacheManager.getCache("push").revrangeSortSetGetAll(userKey);
					messageList.addAll(JsonKit.toArray(messages, ChatBody.class));
				}

				this.putFriendsMessage(messageData, messageList, (String)null);
			}

			List<String> groupIdList = RedisCacheManager.getCache("user").revrangeSortSetGetAll(userId + ":" + "group");
			if (CollectionUtils.isNotEmpty(groupIdList)) {
				groupIdList.forEach((groupId) -> {
					UserMessageData groupMessageData = this.getGroupOfflineMessage(userId, groupId);
					if (!Objects.isNull(groupMessageData)) {
						this.putGroupMessage(messageData, (List)groupMessageData.getGroups().get(groupId));
					}
				});
			}
		} catch (Exception var8) {
			this.log.error(var8.toString(), var8);
		}

		return messageData;
	}

	public UserMessageData getFriendOfflineMessage(String userId, String fromUserId) {
		String userFriendKey = "user:" + userId + ":" + fromUserId;
		List<String> messageList = RedisCacheManager.getCache("push").revrangeSortSetGetAll(userFriendKey);
		List<ChatBody> messageDataList = JsonKit.toArray(messageList, ChatBody.class);
		return this.putFriendsMessage(new UserMessageData(userId), messageDataList, (String)null);
	}

	public UserMessageData getGroupOfflineMessage(String userId, String groupId) {
		UserMessageData messageData = new UserMessageData(userId);
		String userGroupKey = "group:" + groupId + ":" + userId;
		List<String> messages = RedisCacheManager.getCache("push").revrangeSortSetGetAll(userGroupKey);
		if (CollectionUtils.isEmpty(messages)) {
			return messageData;
		} else {
			this.putGroupMessage(messageData, JsonKit.toArray(messages, ChatBody.class));
			return messageData;
		}
	}

	public boolean removeUserOfflineMessage(String userId) {
		try {
			Set<String> userKeys = JedisTemplate.me().keys("push:user:" + userId);
			if (CollectionUtils.isNotEmpty(userKeys)) {
				Iterator<String> userKeyIterator = userKeys.iterator();

				while(userKeyIterator.hasNext()) {
					String userKey = (String)userKeyIterator.next();
					userKey = userKey.substring(userKey.indexOf("user:"));
					RedisCacheManager.getCache("push").remove(userKey);
				}
			}

			List<String> groupIdList = RedisCacheManager.getCache("user").listGetAll(userId + ":" + "group");
			if (CollectionUtils.isNotEmpty(groupIdList)) {
				groupIdList.forEach((groupId) -> {
					this.removeGroupOfflineMessage(userId, groupId);
				});
			}
		} catch (Exception var5) {
			this.log.error(var5.toString(), var5);
		}

		return true;
	}

	public boolean removeFriendOfflineMessage(String userId, String fromUserId) {
		String userFriendKey = "user:" + userId + ":" + fromUserId;
		RedisCacheManager.getCache("push").remove(userFriendKey);
		return true;
	}

	public boolean removeGroupOfflineMessage(String userId, String groupId) {
		String userGroupKey = "group:" + groupId + ":" + userId;
		RedisCacheManager.getCache("push").remove(userGroupKey);
		return true;
	}

	public UserMessageData getFriendHistoryMessage(String userId, String fromUserId, Double beginTime, Double endTime, Integer offset, Integer count) {
		String sessionId = ChatKit.sessionId(userId, fromUserId);
		String userSessionKey = "user:" + sessionId;
		List<String> messages = this.getHistoryMessage(userSessionKey, beginTime, endTime, offset, count);
		UserMessageData messageData = new UserMessageData(userId);
		this.putFriendsMessage(messageData, JsonKit.toArray(messages, ChatBody.class), fromUserId);
		return messageData;
	}

	public UserMessageData getGroupHistoryMessage(String userId, String groupId, Double beginTime, Double endTime, Integer offset, Integer count) {
		String groupKey = "group:" + groupId;
		List<String> messages = this.getHistoryMessage(groupKey, beginTime, endTime, offset, count);
		UserMessageData messageData = new UserMessageData(userId);
		this.putGroupMessage(messageData, JsonKit.toArray(messages, ChatBody.class));
		return messageData;
	}

	private List<String> getHistoryMessage(String historyKey, Double beginTime, Double endTime, Integer offset, Integer count) {
		boolean isTimeBetween = beginTime != null && endTime != null;
		boolean isPage = offset != null && count != null;
		RedisCache storeCache = RedisCacheManager.getCache("store");
		if (isTimeBetween && !isPage) {
			return storeCache.sortSetGetAll(historyKey, beginTime, endTime);
		} else if (isTimeBetween && isPage) {
			return storeCache.revrangeSortSetGetAll(historyKey, beginTime, endTime, offset, count);
		} else {
			return isPage ? storeCache.revrangeSortSetGetAll(historyKey, 0.0, Double.MAX_VALUE, offset, count) : storeCache.sortSetGetAll(historyKey);
		}
	}

	public boolean updateUserTerminal(User user) {
		String userId = user.getUserId();
		String terminal = user.getTerminal();
		String status = user.getStatus();
		if (!StringUtils.isEmpty(userId) && !StringUtils.isEmpty(terminal) && !StringUtils.isEmpty(status)) {
			RedisCacheManager.getCache("user").put(userId + ":" + "terminal" + ":" + terminal, user.getStatus());
			return true;
		} else {
			this.log.error("userId:{},terminal:{},status:{} must not null", new Object[]{userId, terminal, status});
			return false;
		}
	}

	public UserMessageData putFriendsMessage(UserMessageData userMessage, List<ChatBody> messages, String friendId) {
		if (!Objects.isNull(userMessage) && !CollectionUtils.isEmpty(messages)) {
			messages.forEach((chatBody) -> {
				String fromId = chatBody.getFromId();
				if (!StringUtils.isEmpty(fromId)) {
					String targetFriendId = friendId;
					if (StringUtils.isEmpty(friendId)) {
						targetFriendId = fromId;
					}

					List<ChatBody> friendMessages = (List)userMessage.getFriends().get(targetFriendId);
					if (CollectionUtils.isEmpty((Collection)friendMessages)) {
						friendMessages = new ArrayList();
						userMessage.getFriends().put(targetFriendId, friendMessages);
					}

					((List)friendMessages).add(chatBody);
				}
			});
			return userMessage;
		} else {
			return userMessage;
		}
	}

	public UserMessageData putGroupMessage(UserMessageData userMessage, List<ChatBody> messages) {
		if (!Objects.isNull(userMessage) && !CollectionUtils.isEmpty(messages)) {
			messages.forEach((chatBody) -> {
				String groupId = chatBody.getGroupId();
				if (!StringUtils.isEmpty(groupId)) {
					List<ChatBody> groupMessages = (List)userMessage.getGroups().get(groupId);
					if (CollectionUtils.isEmpty((Collection)groupMessages)) {
						groupMessages = new ArrayList();
						userMessage.getGroups().put(groupId, groupMessages);
					}

					((List)groupMessages).add(chatBody);
				}
			});
			return userMessage;
		} else {
			return userMessage;
		}
	}

	static {
		RedisCacheManager.register("user", Integer.MAX_VALUE, Integer.MAX_VALUE);
		RedisCacheManager.register("group", Integer.MAX_VALUE, Integer.MAX_VALUE);
		RedisCacheManager.register("store", Integer.MAX_VALUE, Integer.MAX_VALUE);
		RedisCacheManager.register("push", Integer.MAX_VALUE, Integer.MAX_VALUE);
	}
}
